9cb5f776a3937ecc5333898b86a4e2fe7bb71cee,src/main/java/com/net2plan/examples/general/onlineSim/Online_evProc_wdm.java,Online_evProc_wdm,processEvent,#NetPlan#SimEvent#,189

Before Change


						final Route wdmLayerRoute = WDMUtils.addLightpath(wdmLayerDemand, rwa.getFirst(), lineRateThisLp_Gbps);
						if (DEBUG) checkClashing (currentNetPlan); 
						if (rwa.getFirst().seqLinks.equals(rwa.getSecond().seqLinks)) throw new RuntimeException ("Both 1+1 same route");
						if (DEBUG) checkClashing (currentNetPlan); 
						final Route wdmLayerBackupRoute = WDMUtils.addLightpath(wdmLayerDemand, rwa.getSecond(), 0); // it is a backup, has no traffic carried then
						if (DEBUG) checkClashing (currentNetPlan); 
						wdmLayerRoute.addBackupRoute(wdmLayerBackupRoute);
						if (!WDMUtils.isAllocatableRSASet(wavelengthFiberOccupancy , rwa.getSecond())) throw new RuntimeException ("Bad");
						if (DEBUG) checkClashing (currentNetPlan); 
						WDMUtils.allocateResources(rwa.getSecond() , wavelengthFiberOccupancy , null);
						if (DEBUG) checkClashing (currentNetPlan); 
						WDMUtils.allocateResources(rwa.getFirst() , wavelengthFiberOccupancy , null);
						if (DEBUG) checkClashing (currentNetPlan); 
						checkDisjointness(wdmLayerRoute.getSeqLinks() , rwa.getSecond().seqLinks , protectionTypeCode);
						this.wdmRouteOriginalRwa.put (wdmLayerRoute , rwa);
						this.transponderTypeOfNewLps.put(wdmLayerRoute , transponderTypeUsed);
						this.stat_numCarriedConnections ++;
						this.stat_trafficCarriedConnections += lineRateThisLp_Gbps;
						addLpEvent.lpAddedToFillByProcessor = wdmLayerRoute;
						if (DEBUG) checkClashing (currentNetPlan); 
					}
					if (DEBUG) checkClashing (currentNetPlan); 
				}
				else
				{
					/* The RWA may be computed by me, or mandated by the event */
					WDMUtils.RSA rwa = null;
					int transponderTypeUsed = -1;
					if (addLpEvent.primaryRSA != null)
					{
						if (!WDMUtils.isAllocatableRSASet(wavelengthFiberOccupancy , addLpEvent.primaryRSA))
							throw new Net2PlanException ("A request was received to add a conflicting lightpath");
						rwa = addLpEvent.primaryRSA; 
					}
					else
					{
						/* Check among the transponder types (in order), the one in the same rate that fits (optical reach in range). */
						for (int t = 0; t < tpInfo.getNumTypes() ; t ++)
						{
							if (lineRateThisLp_Gbps != tpInfo.getLineRateGbps(t)) continue;
							rwa = computeValidPathNewRoute(cplNodePair , currentNetPlan , tpInfo.getNumSlots(t) , tpInfo.getOpticalReachKm(t) , tpInfo.isOpticalRegenerationPossible(t));
							if (rwa != null) { transponderTypeUsed = t; break; }
						}
					}
//				System.out.println ("------ ADD LP: rwa: " + rwa);
					if (rwa != null)
					{
						final Demand wdmLayerDemand = addLpEvent.demand == null? currentNetPlan.addDemand(addLpEvent.ingressNode, addLpEvent.egressNode, lineRateThisLp_Gbps , null, wdmLayer) : addLpEvent.demand;
						final Route wdmLayerRoute = WDMUtils.addLightpath(wdmLayerDemand, rwa , lineRateThisLp_Gbps);
						WDMUtils.allocateResources(rwa , wavelengthFiberOccupancy , null);
						this.wdmRouteOriginalRwa.put (wdmLayerRoute , Pair.of(rwa,(WDMUtils.RSA)null));
						this.transponderTypeOfNewLps.put(wdmLayerRoute , transponderTypeUsed);
						this.stat_numCarriedConnections ++;
						this.stat_trafficCarriedConnections += lineRateThisLp_Gbps;
						addLpEvent.lpAddedToFillByProcessor = wdmLayerRoute;
//					System.out.println ("Added lp: " + wdmLayerRoute);
					}
				}
				if (DEBUG) checkClashing (currentNetPlan); 
			}
			else if (event.getEventObject () instanceof WDMUtils.LightpathRemove)
			{
				WDMUtils.LightpathRemove lpEvent = (WDMUtils.LightpathRemove) event.getEventObject ();
				final Route lpToRemove = lpEvent.lp;
				final Pair<WDMUtils.RSA,WDMUtils.RSA> originalRwa = wdmRouteOriginalRwa.get(lpToRemove);
				if (originalRwa == null) return; // the ligtpath was already removed, because it was first accepted, but then blocked because of failures 
				if (isRestorationRecovery) // restoration => the current route is the one to release
					removeRoute_restoration(lpToRemove);
				else
					removeRoute_protection(lpToRemove , originalRwa);
				this.transponderTypeOfNewLps.remove(lpToRemove);
				if (DEBUG) checkClashing (currentNetPlan); 
			} else if (event.getEventObject () instanceof SimEvent.NodesAndLinksChangeFailureState)
			{
				SimEvent.NodesAndLinksChangeFailureState ev = (SimEvent.NodesAndLinksChangeFailureState) event.getEventObject ();

//				System.out.println ("----------- Event NodesAndLinksChangeFailureState: links up" + ev.linksToUp + ", links down: " + ev.linksToDown);

				if (DEBUG) checkClashing (currentNetPlan); 

				/* This automatically sets as up the routes affected by a repair in its current path, and sets as down the affected by a failure in its current path */
				Set<Route> routesFromDownToUp = currentNetPlan.getRoutesDown(wdmLayer);
				currentNetPlan.setLinksAndNodesFailureState(ev.linksToUp , ev.linksToDown , ev.nodesToUp , ev.nodesToDown);
				routesFromDownToUp.removeAll(currentNetPlan.getRoutesDown(wdmLayer));

				/* If something failed, and I am supposed to use protection or restoration... */
				if (isProtectionRecovery)
				{
					/* POLICY WITH PROTECTION: */
					/* Primary up => backup carried traffic in no failure state is zero */
					/* Primary down => backup carried traffic in no failure state is equal to the carried in no failure of the primary */

					/* If primary GOES up => backup carried is set to zero */ 
					for (Route r : routesFromDownToUp)
						if (r.hasBackupRoutes()) r.getBackupRoutes().get(0).setCarriedTraffic(0, null); // primary to up => carried in backup to zero
					/* Now for the each primary route that is down, set backup carried to the one of the primary, but count recovered only if backup is up */
					for (Route r : currentNetPlan.getRoutesDown(wdmLayer).stream().filter(e -> !e.isBackupRoute()).collect(Collectors.toSet()))
					{
						if (r.isBackupRoute()) continue;
						this.stat_numAttemptedToRecoverConnections ++;
						this.stat_trafficAttemptedToRecoverConnections += r.getCarriedTrafficInNoFailureState();
						/* The primary routes goes down => its backup has now carried traffic (if no failure) */
						if (r.hasBackupRoutes())
						{
							final Route backupRoute = r.getBackupRoutes().get(0);
							backupRoute.setCarriedTraffic(r.getCarriedTrafficInNoFailureState(), null);
							if (!backupRoute.isDown())
							{
								this.stat_numSuccessfullyRecoveredConnections ++; 
								this.stat_trafficSuccessfullyRecoveredConnections += r.getCarriedTrafficInNoFailureState(); 
							}
						}
					}					
				}
				else if (isRestorationRecovery)
				{
					for (Route r : new HashSet<Route> (currentNetPlan.getRoutesDown(wdmLayer)))
					{
						this.stat_numAttemptedToRecoverConnections ++;
						this.stat_trafficAttemptedToRecoverConnections += r.getCarriedTrafficInNoFailureState();
						final Pair<Node,Node> cplNodePair= Pair.of(r.getIngressNode() , r.getEgressNode());
						final Integer transponderTypeLp = transponderTypeOfNewLps.get(r);
						final double maxOpticalReachKm = transponderTypeLp == null? Double.MAX_VALUE : tpInfo.getOpticalReachKm(transponderTypeLp);
						final boolean isSignalRegenerationPossible = transponderTypeLp == null? true : tpInfo.isOpticalRegenerationPossible(transponderTypeLp); 
						final int numSlots = transponderTypeLp == null? new WDMUtils.RSA(r,false).getNumSlots() : tpInfo.getNumSlots(transponderTypeLp);
						WDMUtils.RSA rwa = computeValidPathNewRoute (cplNodePair , currentNetPlan , numSlots , maxOpticalReachKm , isSignalRegenerationPossible);
						if (rwa != null)
						{ 
							WDMUtils.releaseResources(new WDMUtils.RSA (r , false) , wavelengthFiberOccupancy, null);
							WDMUtils.allocateResources(rwa , wavelengthFiberOccupancy , null);
							r.setSeqLinks(rwa.seqLinks);
							WDMUtils.setLightpathRSAAttributes(r , rwa , false);
							
							this.stat_numSuccessfullyRecoveredConnections ++; 
							this.stat_trafficSuccessfullyRecoveredConnections += r.getCarriedTrafficInNoFailureState(); 
						}
					}					
				}
				if (DEBUG) checkClashing (currentNetPlan); 
			} else if (event.getEventObject () instanceof SimEvent.DemandModify)
			{
				SimEvent.DemandModify ev = (SimEvent.DemandModify) event.getEventObject ();
				Demand d = ev.demand; 
				if (ev.modificationIsRelativeToCurrentOfferedTraffic) 
					d.setOfferedTraffic(d.getOfferedTraffic() + ev.offeredTraffic);
				else
					d.setOfferedTraffic(ev.offeredTraffic);
				if (DEBUG) checkClashing (currentNetPlan); 
			} else if (event.getEventObject () instanceof SimEvent.DemandRemove)
			{
				SimEvent.DemandRemove ev = (SimEvent.DemandRemove) event.getEventObject ();

After Change


	}

	@Override
	public void processEvent(NetPlan currentNetPlan, SimEvent event)
	{
		try {
			if (event.getEventObject () instanceof WDMUtils.LightpathAdd)
			{
				WDMUtils.LightpathAdd addLpEvent = (WDMUtils.LightpathAdd) event.getEventObject ();
				if (addLpEvent.layer != this.wdmLayer) throw new Net2PlanException ("Lightpaths cannot be added to layer " + addLpEvent.demand.getLayer() + ", and just to the WDM layer (" + wdmLayer + ")");
				final Node ingressNode = addLpEvent.ingressNode;
				final Node egressNode = addLpEvent.egressNode;
				final Pair<Node,Node> cplNodePair = Pair.of(ingressNode,egressNode);
				final double lineRateThisLp_Gbps = addLpEvent.lineRateGbps;
				if (!tpInfo.isValidLineRateForAtLeastOneType (lineRateThisLp_Gbps)) throw new Net2PlanException ("Requested to set up a lightpath of a line rate (" + lineRateThisLp_Gbps + ") for which I don't have transpoders");

				/* update the offered traffic of the demand */
				this.stat_numOfferedConnections ++;
				this.stat_trafficOfferedConnections += lineRateThisLp_Gbps;
				
				/* Computes one or two paths over the links (the second path would be a segment). You cannot use the already existing segments in these paths */
				if (newRoutesHave11Protection)
				{
					/* The RWA may be computed by me, or mandated by the event */
					Pair<WDMUtils.RSA,WDMUtils.RSA> rwa = null;
					int transponderTypeUsed = -1;
					if ((addLpEvent.primaryRSA != null) && (addLpEvent.backupRSA != null))
					{
						if (!WDMUtils.isAllocatableRSASet(wavelengthFiberOccupancy , addLpEvent.primaryRSA , addLpEvent.backupRSA))
							throw new Net2PlanException ("A request was received to add a conflicting lightpath 1+1 pair");
						rwa = Pair.of (addLpEvent.primaryRSA , addLpEvent.backupRSA);
					}
					else
					{
						/* Check among the transponder types (in order), the one in the same rate that fits (optical reach in range). */
						for (int t = 0; t < tpInfo.getNumTypes() ; t ++)
						{
							if (lineRateThisLp_Gbps != tpInfo.getLineRateGbps(t)) continue;
							rwa = computeValid11PathPairNewRoute(cplNodePair , currentNetPlan , tpInfo.getNumSlots(t) , tpInfo.getOpticalReachKm(t) , tpInfo.isOpticalRegenerationPossible(t));
							if (rwa != null) { transponderTypeUsed = t; break; }
						}
					}

					if (rwa != null)
					{
						if (!WDMUtils.isAllocatableRSASet(wavelengthFiberOccupancy , rwa.getFirst() , rwa.getSecond())) throw new RuntimeException ("Bad");
						if (!WDMUtils.isAllocatableRSASet(wavelengthFiberOccupancy , rwa.getSecond())) throw new RuntimeException ("Bad");
						for (Link e : rwa.getFirst ().seqLinks) if (e.getNetPlan() != currentNetPlan) throw new RuntimeException ("Bad. e.getNetPlan is null?: " + (e.getNetPlan() ==null) + ", currentNp is null: " + (currentNetPlan == null));
						for (Link e : rwa.getSecond ().seqLinks) if (e.getNetPlan() != currentNetPlan) throw new RuntimeException ("Bad");

						if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 
						
						final Demand wdmLayerDemand = addLpEvent.demand == null? currentNetPlan.addDemand(addLpEvent.ingressNode, addLpEvent.egressNode, lineRateThisLp_Gbps , null, wdmLayer) : addLpEvent.demand;
						final Route wdmLayerRoute = WDMUtils.addLightpath(wdmLayerDemand, rwa.getFirst(), lineRateThisLp_Gbps);
						WDMUtils.allocateResources(rwa.getFirst() , wavelengthFiberOccupancy , null);

						if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 

						if (rwa.getFirst().seqLinks.equals(rwa.getSecond().seqLinks)) throw new RuntimeException ("Both 1+1 same route");
						final Route wdmLayerBackupRoute = WDMUtils.addLightpath(wdmLayerDemand, rwa.getSecond(), 0); // it is a backup, has no traffic carried then
						wdmLayerRoute.addBackupRoute(wdmLayerBackupRoute);
						WDMUtils.allocateResources(rwa.getSecond() , wavelengthFiberOccupancy , null);
						if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 
						checkDisjointness(wdmLayerRoute.getSeqLinks() , rwa.getSecond().seqLinks , protectionTypeCode);
						this.wdmRouteOriginalRwa.put (wdmLayerRoute , rwa);
						this.transponderTypeOfNewLps.put(wdmLayerRoute , transponderTypeUsed);
						this.stat_numCarriedConnections ++;
						this.stat_trafficCarriedConnections += lineRateThisLp_Gbps;
						addLpEvent.lpAddedToFillByProcessor = wdmLayerRoute;
						if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 
					}
					if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 
				}
				else
				{
					/* The RWA may be computed by me, or mandated by the event */
					WDMUtils.RSA rwa = null;
					int transponderTypeUsed = -1;
					if (addLpEvent.primaryRSA != null)
					{
						if (!WDMUtils.isAllocatableRSASet(wavelengthFiberOccupancy , addLpEvent.primaryRSA))
							throw new Net2PlanException ("A request was received to add a conflicting lightpath");
						rwa = addLpEvent.primaryRSA; 
					}
					else
					{
						/* Check among the transponder types (in order), the one in the same rate that fits (optical reach in range). */
						for (int t = 0; t < tpInfo.getNumTypes() ; t ++)
						{
							if (lineRateThisLp_Gbps != tpInfo.getLineRateGbps(t)) continue;
							rwa = computeValidPathNewRoute(cplNodePair , currentNetPlan , tpInfo.getNumSlots(t) , tpInfo.getOpticalReachKm(t) , tpInfo.isOpticalRegenerationPossible(t));
							if (rwa != null) { transponderTypeUsed = t; break; }
						}
					}
					if (rwa != null)
					{
						final Demand wdmLayerDemand = addLpEvent.demand == null? currentNetPlan.addDemand(addLpEvent.ingressNode, addLpEvent.egressNode, lineRateThisLp_Gbps , null, wdmLayer) : addLpEvent.demand;
						final Route wdmLayerRoute = WDMUtils.addLightpath(wdmLayerDemand, rwa , lineRateThisLp_Gbps);
						WDMUtils.allocateResources(rwa , wavelengthFiberOccupancy , null);
						this.wdmRouteOriginalRwa.put (wdmLayerRoute , Pair.of(rwa,(WDMUtils.RSA)null));
						this.transponderTypeOfNewLps.put(wdmLayerRoute , transponderTypeUsed);
						this.stat_numCarriedConnections ++;
						this.stat_trafficCarriedConnections += lineRateThisLp_Gbps;
						addLpEvent.lpAddedToFillByProcessor = wdmLayerRoute;
					}
				}
				if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 
			}
			else if (event.getEventObject () instanceof WDMUtils.LightpathRemove)
			{
				WDMUtils.LightpathRemove lpEvent = (WDMUtils.LightpathRemove) event.getEventObject ();
				final Route lpToRemove = lpEvent.lp;
				final Pair<WDMUtils.RSA,WDMUtils.RSA> originalRwa = wdmRouteOriginalRwa.get(lpToRemove);
				if (originalRwa == null) return; // the ligtpath was already removed, because it was first accepted, but then blocked because of failures 
				if (isRestorationRecovery) // restoration => the current route is the one to release
					removeRoute_restoration(lpToRemove);
				else
					removeRoute_protection(lpToRemove , originalRwa);
				this.transponderTypeOfNewLps.remove(lpToRemove);
				if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 
			} else if (event.getEventObject () instanceof SimEvent.NodesAndLinksChangeFailureState)
			{
				SimEvent.NodesAndLinksChangeFailureState ev = (SimEvent.NodesAndLinksChangeFailureState) event.getEventObject ();

				if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 

				/* This automatically sets as up the routes affected by a repair in its current path, and sets as down the affected by a failure in its current path */
				Set<Route> routesFromDownToUp = currentNetPlan.getRoutesDown(wdmLayer);
				currentNetPlan.setLinksAndNodesFailureState(ev.linksToUp , ev.linksToDown , ev.nodesToUp , ev.nodesToDown);
				routesFromDownToUp.removeAll(currentNetPlan.getRoutesDown(wdmLayer));

				/* If something failed, and I am supposed to use protection or restoration... */
				if (isProtectionRecovery)
				{
					/* POLICY WITH PROTECTION: */
					/* Primary up => backup carried traffic in no failure state is zero */
					/* Primary down => backup carried traffic in no failure state is equal to the carried in no failure of the primary */

					/* If primary GOES up => backup carried is set to zero */ 
					for (Route r : routesFromDownToUp)
						if (r.hasBackupRoutes()) r.getBackupRoutes().get(0).setCarriedTraffic(0, null); // primary to up => carried in backup to zero
					/* Now for the each primary route that is down, set backup carried to the one of the primary, but count recovered only if backup is up */
					for (Route r : currentNetPlan.getRoutesDown(wdmLayer).stream().filter(e -> !e.isBackupRoute()).collect(Collectors.toSet()))
					{
						if (r.isBackupRoute()) continue;
						this.stat_numAttemptedToRecoverConnections ++;
						this.stat_trafficAttemptedToRecoverConnections += r.getCarriedTrafficInNoFailureState();
						/* The primary routes goes down => its backup has now carried traffic (if no failure) */
						if (r.hasBackupRoutes())
						{
							final Route backupRoute = r.getBackupRoutes().get(0);
							backupRoute.setCarriedTraffic(r.getCarriedTrafficInNoFailureState(), null);
							if (!backupRoute.isDown())
							{
								this.stat_numSuccessfullyRecoveredConnections ++; 
								this.stat_trafficSuccessfullyRecoveredConnections += r.getCarriedTrafficInNoFailureState(); 
							}
						}
					}					
				}
				else if (isRestorationRecovery)
				{
					for (Route r : new HashSet<Route> (currentNetPlan.getRoutesDown(wdmLayer)))
					{
						this.stat_numAttemptedToRecoverConnections ++;
						this.stat_trafficAttemptedToRecoverConnections += r.getCarriedTrafficInNoFailureState();
						final Pair<Node,Node> cplNodePair= Pair.of(r.getIngressNode() , r.getEgressNode());
						final Integer transponderTypeLp = transponderTypeOfNewLps.get(r);
						final double maxOpticalReachKm = transponderTypeLp == null? Double.MAX_VALUE : tpInfo.getOpticalReachKm(transponderTypeLp);
						final boolean isSignalRegenerationPossible = transponderTypeLp == null? true : tpInfo.isOpticalRegenerationPossible(transponderTypeLp); 
						final int numSlots = transponderTypeLp == null? new WDMUtils.RSA(r,false).getNumSlots() : tpInfo.getNumSlots(transponderTypeLp);
						WDMUtils.RSA rwa = computeValidPathNewRoute (cplNodePair , currentNetPlan , numSlots , maxOpticalReachKm , isSignalRegenerationPossible);
						if (rwa != null)
						{ 
							WDMUtils.releaseResources(new WDMUtils.RSA (r , false) , wavelengthFiberOccupancy, null);
							WDMUtils.allocateResources(rwa , wavelengthFiberOccupancy , null);
							r.setSeqLinks(rwa.seqLinks);
							WDMUtils.setLightpathRSAAttributes(r , rwa , false);
							
							this.stat_numSuccessfullyRecoveredConnections ++; 
							this.stat_trafficSuccessfullyRecoveredConnections += r.getCarriedTrafficInNoFailureState(); 
						}
					}					
				}
				if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 
			} else if (event.getEventObject () instanceof SimEvent.DemandModify)
			{
				SimEvent.DemandModify ev = (SimEvent.DemandModify) event.getEventObject ();
				Demand d = ev.demand; 
				if (ev.modificationIsRelativeToCurrentOfferedTraffic) 
					d.setOfferedTraffic(d.getOfferedTraffic() + ev.offeredTraffic);
				else
					d.setOfferedTraffic(ev.offeredTraffic);
				if (DEBUG) { checkWaveOccupEqualsNp(currentNetPlan); checkClashing (currentNetPlan); } 
			} else if (event.getEventObject () instanceof SimEvent.DemandRemove)
			{
				SimEvent.DemandRemove ev = (SimEvent.DemandRemove) event.getEventObject ();